
# include "SocketWin.h"

unsigned int SocketImpl::_counter = 0;
WSADATA SocketImpl::_wsa = {0};

SocketImpl::SocketImpl()
{
    if (SocketImpl::_counter == 0)
    {
        WSAStartup(MAKEWORD(2, 2), &SocketImpl::_wsa);
    }
    SocketImpl::_counter++;
}

SocketImpl::~SocketImpl()
{
    SocketImpl::_counter--;
    if (SocketImpl::_counter == 0)
    {
        WSACleanup();
    }
}

SocketImpl::SocketImpl(SocketImpl const & impl)
  : _sock(impl._sock), _domain(impl._domain), _tyep(impl._type),_service(impl._service)
{
    SocketImpl::_counter++;
}

SocketImpl& SocketImpl::operator=(SocketImpl const & impl)
{
    if (this != &impl)
    {
        _sock = impl._sock;
	_domain = impl._domain;
	_type = impl._type;
        _service = impl._service;
    }
    return *this;
}

void SocketImpl::open(int domain, int type)
{
    _domain = domain;
    _type = type;
    _sock = WSASocket(domain, type, 0, NULL, 0, 0);
}

void SocketImpl::bind(int port, char *addr)
{
  if (addr == NULL)
    _service.sin_addr.s_addr = INADDR_ANY;
  else
    _service.sin_addr.s_addr = inet_addr(addr);
    _service.sin_family = _domain;
    _service.sin_port = htons(port);

    res = ::bind(_sock, (SOCKADDR *) & _service, sizeof(_service));
}
 
void SocketImpl::listen(int backlog)
{
    ::listen(_sock, backlog);
}
 
void SocketImpl::accept(ISocket *nsock)
{
    SocketImpl *csock;

    csock = dynamic_cast<SocketImpl *>(nsock);
    csock->_sock = WSAAccept(_sock, (SOCKADDR *)&csock->_service, (LPINT)sizeof(csock->_service), NULL, NULL);
}

void SocketImpl::connect(int port, char *addr)
{
    int res;

    res = WSAConnect(_sock, (SOCKADDR *) & addr, 0, NULL, NULL, NULL, NULL);
}

int SocketImpl::send(const void *msg, size_t len)
{
    int res;
    WSABUF wbuf;
    wbuf.len = len;
    wbuf.buf = (char *)msg;
 
    res = WSASend(_sock, &wbuf, len, NULL, NULL, NULL, NULL);
    return res;
}

int SocketImpl::recv(void *buf, size_t len)
{
    int res;
    WSABUF wbuf;
    wbuf.len = len;
    wbuf.buf = (char *)buf;

    res = WSARecv(_sock, &wbuf, len, NULL, NULL, NULL, NULL);
    return res;
}

void SocketImpl::close()
{
    int res;

    res = closesocket(_sock);
}
